﻿package {
	/*
	 * Object Browser
	 * by Sunny Goyal
	 * */
	
	import flash.display.Sprite;
	import flash.display.StageDisplayState;
	import flash.utils.Timer;

	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.events.FullScreenEvent;
	import flash.events.TimerEvent;

	import org.papervision3d.view.Viewport3D; // We need a viewport
	import org.papervision3d.cameras.Camera3D; // Import all types of camera
	import org.papervision3d.scenes.Scene3D; // We'll need at least one scene
	import org.papervision3d.render.BasicRenderEngine; // And we need a renderer

	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.parsers.Collada;
	
	public class Main extends Sprite {
		
		public var cState:Number = 2;
		
		public var tbTimer:Timer = new Timer(10,0);
		public var tbHide:Boolean = true;
		public var tbDelay:Number = 1000;
		
		public var cam:Object = {
			r:1000,
			theta:0,
			phi:0,
			mx:0,
			my:0,
			focus:DisplayObject3D.ZERO,
			lastFocusPos: null,
			rOld:1000,
			thetaOld : 0,
			phiOld : 0
		};
		
		public var viewport:Viewport3D; // The Viewport
		public var renderer:BasicRenderEngine; // Rendering engine
		
		public var scene:Scene3D; // A Scene
		public var camera:Camera3D; // A Camera
		
		
		public var model:DisplayObject3D;
		
		public function setState(s:Number):void {
			toolbar["but" + cState].gotoAndPlay("up");
			toolbar["but" + cState].button.visible = true;
			cState = s;
			toolbar["but" + cState].gotoAndPlay("down");
			toolbar["but" + cState].button.visible = false;
		}
		
		protected function onMouseUp( ThisEvent:Event ):void {
			removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}


		private function setCam():void {
			camera.y = Math.sin(cam.phi) * cam.r + cam.focus.y;
			camera.x = Math.cos(cam.phi) * cam.r*Math.sin(cam.theta) + cam.focus.x;
			camera.z = Math.cos(cam.phi) * cam.r*Math.cos(cam.theta) + cam.focus.z;
			
			camera.rotationX = -180 + cam.phi*180/Math.PI;
			camera.rotationY = -cam.theta*180/Math.PI;
			camera.rotationZ = 180;
		}
		
		protected function onMouseMove( ThisEvent:Event ):void {
			if(cState == 0){
				cam.focus.x = cam.lastFocusPos.x + (2000/cam.r)*(mouseX - cam.mx)*Math.cos(cam.theta);
				cam.focus.y = cam.lastFocusPos.y + (2000/cam.r)*(mouseY - cam.my)*Math.cos(cam.phi);
				cam.focus.z = cam.lastFocusPos.z + (2000/cam.r)*(mouseX - cam.mx)*Math.sin(-cam.theta) + (mouseY - cam.my)*Math.sin(-cam.phi);
				setCam();
			} else if (cState == 1){
				cam.theta = cam.thetaOld + (mouseX - cam.mx)*Math.PI/225;
				cam.phi = cam.phiOld + (mouseY - cam.my)*Math.PI/180;
				setCam();
			}  else if (cState == 2){
				cam.r = cam.rOld - 10*(mouseX - cam.mx);
				if (cam.r < 10) cam.r = 10;
				setCam();
			}
		}
		
		protected function onMouseDown( ThisEvent:Event ):void {
		
			cam.mx = mouseX;
			cam.my = mouseY;
			
			cam.lastFocusPos = cam.focus.position;
			cam.rOld = cam.r;
			cam.thetaOld = cam.theta;
			cam.phiOld = cam.phi;
			
			addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
		
		public function Main() {
			viewport = new Viewport3D(400, 300,false,true);
			sceneHolder.addChild(viewport); // Add the viewport to the stage.
			
			renderer = new BasicRenderEngine();
			scene = new Scene3D();
			camera = new Camera3D();
			
			
			model = new Collada("model.dae");
			scene.addChild(model);
			
			scene.addChild(cam.focus);
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
						
			setState(0);
			toolbar.but0.button.addEventListener(MouseEvent.MOUSE_DOWN, function(){ setState(0); } );
			toolbar.but1.button.addEventListener(MouseEvent.MOUSE_DOWN, function(){ setState(1); } );
			toolbar.but2.button.addEventListener(MouseEvent.MOUSE_DOWN, function(){ setState(2); } );
			
			toolbar.butHome.button.addEventListener(MouseEvent.CLICK, function(){ cam.r=1000;cam.theta=cam.phi=cam.focus.x=cam.focus.y=cam.focus.z=0; setCam();} );
			toolbar.butfullScreen.button.addEventListener(MouseEvent.CLICK,
									function(){
										if (stage.displayState == StageDisplayState.NORMAL) {
											stage.displayState=StageDisplayState.FULL_SCREEN;
										} else {
											stage.displayState=StageDisplayState.NORMAL;
										}
									}
							);
			
			stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen);
			sceneHolder.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			setCam();
			
			toolbar.addEventListener(MouseEvent.MOUSE_OVER, showToolbar);
			toolbar.addEventListener(MouseEvent.MOUSE_OUT, delayedHideToolbar);
			tbTimer.addEventListener(TimerEvent.TIMER, controlTimer);
		}
		
		private function showToolbar( ThisEvent:Event ):void {
			tbHide = false;
			tbTimer.start();
		}
		
		private function delayedHideToolbar( ThisEvent:Event ):void {
			tbHide = true;
			tbDelay = 200;
			tbTimer.start();
		}
		
		private function controlTimer (ThisEvent:TimerEvent):void{
			if(tbHide){
				if(tbDelay>0){
					if(toolbar.y > 270){
						toolbar.y -= 1;
					} else {
						tbDelay--;
					}
				} else {
					if(toolbar.y >= 290) {
						tbTimer.stop();
					} else {
						toolbar.y += 1;
						
					}
				}
			} else {
				if(toolbar.y <= 270) {
						tbTimer.stop();
					} else {
						toolbar.y -= 1;
					}
			}
		}
		
		private function handleFullScreen(event:FullScreenEvent):void {
			if(event.fullScreen) {
				 toolbar.butfullScreen.gotoAndPlay("down");
			} else {
				toolbar.butfullScreen.gotoAndPlay("up");
			}
		}

		protected function onEnterFrame( ThisEvent:Event ):void {
			renderer.renderScene(scene, camera, viewport);
		}
	}
	
	
}